package com.aia.prm.web.ria.app.ui.file;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;

import com.aia.prm.domain.VOFile;
import com.aia.prm.web.ria.app.ui.ConfirmDialog;
import com.cfh.util.Tools;
import com.vaadin.data.Item;
import com.vaadin.data.Validator;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.validator.RegexpValidator;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Component;
import com.vaadin.ui.DefaultFieldFactory;
import com.vaadin.ui.Field;
import com.vaadin.ui.Form;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.TextField;
import com.vaadin.ui.Upload;
import com.vaadin.ui.Upload.FailedEvent;
import com.vaadin.ui.Upload.FinishedEvent;
import com.vaadin.ui.Upload.StartedEvent;
import com.vaadin.ui.Upload.SucceededEvent;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window.Notification;

@SuppressWarnings("serial")
public class FileForm extends Form implements ClickListener {
	private static final Logger logger = Logger.getLogger(FileForm.class);
	private Button save = new Button("保存(不更改二进制数据)", (ClickListener) this);
	private Button cancel = new Button("取消", (ClickListener) this);
	private Button edit = new Button("编辑", (ClickListener) this);
	private Button delete = new Button("删除", (ClickListener) this);

	private MyReceiver receiver = new MyReceiver();
	private Upload upload = new Upload(null, receiver);

	private boolean newContactMode = false;
	private VOFile newVOFile = null;
	FileView view = null;

	public void doSave(byte[] byteArray) {
		if (!isValid()) {
			return;
		}
		logger.debug("ready to Save");
		commit();
		if (!newContactMode) {
			BeanItem item = (BeanItem) getItemDataSource();
			VOFile config = (VOFile) item.getBean();
			int cnt = 0;
			if (byteArray != null) {
				config.setF_BIN(byteArray);
				cnt = view.getFileDAO().updateByPrimaryKeyWithBLOBs(config);
			} else {
				config.setF_BIN(null);
				cnt = view.getFileDAO().updateByPrimaryKeyWithoutBLOBs(config);
			}
			getApplication().getMainWindow().showNotification("修改成功, 影响记录数:" + cnt);
			view.load();
		} else if (newContactMode) {
			Item addedItem = view.FileContainer.addItem(newVOFile);
			BeanItem item = (BeanItem) getItemDataSource();
			VOFile config = (VOFile) item.getBean();
			if (byteArray != null) {
				config.setF_BIN(byteArray);
			} else {
				config.setF_BIN(null);
			}
			config.setF_DATE(Tools.getToday());
			config.setF_TIME(Tools.getTime());

			view.getFileDAO().insertSelective(config);
			getApplication().getMainWindow().showNotification("添加成功");
			view.load();
			newContactMode = false;
		}
		setReadOnly(true);
	}

	public FileForm(FileView aview) {
		upload.setButtonCaption("上传文件并保存");
		upload.addListener(new Upload.StartedListener() {
			public void uploadStarted(StartedEvent event) {
				if (!isValid()) {
					getApplication().getMainWindow().showNotification("请正确输入", Notification.TYPE_WARNING_MESSAGE);
					upload.interruptUpload();
					return;
				}

				logger.debug("uploadStarted,getContentLength=" + event.getContentLength());
				logger.debug("uploadStarted,getMIMEType=" + event.getMIMEType());
				long maxSize = 2L * 1024L * 1024L * 8L; // 2MB
				if (event.getContentLength() > maxSize) {
					getApplication().getMainWindow().showNotification("上传文件过大", Notification.TYPE_WARNING_MESSAGE);
					logger.debug("event.getContentLength() > " + maxSize + ";  interruptUpload!");
					upload.interruptUpload();
					return;
				}
				getApplication().getMainWindow().showNotification("开始上传文件 \"" + event.getFilename() + "\"",
						Notification.TYPE_TRAY_NOTIFICATION);
			}
		});

		upload.addListener(new Upload.SucceededListener() {
			public void uploadSucceeded(SucceededEvent event) {
				// This method gets called when the upload finished successfully
				logger.debug("uploadSucceeded");
				ByteArrayOutputStream out = receiver.getByteArrayOutputStream();
				byte[] byteArray = out.toByteArray();
				logger.debug("byteArray.length=" + byteArray.length);
				try {
					FileUtils.writeByteArrayToFile(new File("D:/test.txt"), byteArray);
					logger.debug("OK: FileUtils.writeByteArrayToFile(new File('D:/test.txt'), byteArray);");
				} catch (IOException e) {
					logger.warn(e);
				}
				getApplication().getMainWindow().showNotification("文件上传成功! \"" + event.getFilename() + "\"",
						Notification.TYPE_TRAY_NOTIFICATION);

				doSave(byteArray);

			}
		});

		upload.addListener(new Upload.FailedListener() {
			public void uploadFailed(FailedEvent event) {
				logger.debug("uploadFailed");
				receiver.clean();
				getApplication().getMainWindow().showNotification("上传文件失败", Notification.TYPE_WARNING_MESSAGE);
			}
		});

		upload.addListener(new Upload.FinishedListener() {
			public void uploadFinished(FinishedEvent event) {
				// This method gets called always when the upload finished,
				// either succeeding or failing
				receiver.clean();
				logger.debug("uploadFinished");
			}
		});

		setIcons();
		view = aview;
		getLayout().setMargin(true);
		// setCaption("");
		setSizeFull();
		setWriteThrough(false);
		HorizontalLayout footer0 = new HorizontalLayout();
		footer0.setSpacing(true);
		footer0.addComponent(upload);

		HorizontalLayout footer = new HorizontalLayout();
		footer.setSpacing(true);
		footer.addComponent(save);
		footer.addComponent(cancel);
		footer.addComponent(edit);
		footer.addComponent(delete);

		VerticalLayout verticalLayout = new VerticalLayout();
		verticalLayout.setSizeUndefined();
		verticalLayout.setSpacing(true);
		verticalLayout.addComponent(footer0);
		verticalLayout.addComponent(footer);
		verticalLayout.setVisible(false);
		setFooter(verticalLayout);
		setFormFieldFactory(new DefaultFieldFactory() {
			public Field createField(Item item, Object propertyId, Component uiContext) {
				Field field = super.createField(item, propertyId, uiContext);
				if (field instanceof TextField) {
					((TextField) field).setNullRepresentation("");
					((TextField) field).setNullSettingAllowed(true);
				}
				if (FileContainer.FIELD_NAME_MAP.containsKey(propertyId)) {
					field.setCaption(FileContainer.FIELD_NAME_MAP.get(propertyId));
				}
				if ("f_ID".equals(propertyId)) {
					if (field instanceof TextField) {
						((TextField) field).setRequired(true);
						((TextField) field).setRequiredError("必填项");
						//((TextField) field).addValidator(new RegexpValidator("[A-Za-z0-9]+", "请输入英文与数字"));
					}
				}

				return field;
			}
		});
	}

	private void setIcons() {
		delete.setIcon(new ThemeResource("icons/delete.png"));
		edit.setIcon(new ThemeResource("icons/edit.png"));
		save.setIcon(new ThemeResource("icons/accept.png"));
		cancel.setIcon(new ThemeResource("icons/back.png"));
		setIcon(new ThemeResource("icons/comment_edit.png"));
	}

	public void buttonClick(ClickEvent event) {
		Button source = event.getButton();

		if (source == save) {
			doSave(null);
		} else if (source == cancel) {
			if (newContactMode) {
				newContactMode = false;
				/* Clear the form and make it invisible */
				setItemDataSource(null);
			} else {
				discard();
			}
			setReadOnly(true);
		} else if (source == delete) {
			ConfirmDialog.confirmYesNo(getApplication(), "确定吗?", new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					BeanItem item = (BeanItem) FileForm.this.getItemDataSource();
					if (item == null) {
						getApplication().getMainWindow().showNotification("找不到数据");
						return;
					}
					VOFile config = (VOFile) item.getBean();
					view.getFileDAO().deleteByPrimaryKey(config.getF_ID());
					setItemDataSource(null);
					view.load();
				}
			});

		} else if (source == edit) {
			setReadOnly(false);
		}
	}

	@Override
	public void setItemDataSource(Item newDataSource) {
		newContactMode = false;

		if (newDataSource != null) {
			super.setItemDataSource(newDataSource);
			List<Object> orderedProperties = Arrays.asList(FileContainer.NATURAL_COL_ORDER_FORM);
			super.setItemDataSource(newDataSource, orderedProperties);
			setReadOnly(true);
			getFooter().setVisible(true);
		} else {
			super.setItemDataSource(null);
			getFooter().setVisible(false);
		}
	}

	@Override
	public void setReadOnly(boolean readOnly) {
		super.setReadOnly(readOnly);
		if (!newContactMode && getItemDataSource() != null) {
			setReadOnlyByFieldName("f_ID");
			setReadOnlyByFieldName("f_DATE");
		}
		upload.setVisible(!readOnly);
		save.setVisible(!readOnly);
		cancel.setVisible(!readOnly);
		edit.setVisible(readOnly);
		delete.setVisible(readOnly);
	}

	private void setReadOnlyByFieldName(String string) {
		Field f = getField(string);
		if (f != null) {
			f.setReadOnly(true);
		} else {
			logger.warn("field is null:" + string);
		}

	}

	public void addObject() {
		// Create a temporary item for the form
		newVOFile = new VOFile();
		setItemDataSource(new BeanItem<VOFile>(newVOFile));
		newContactMode = true;
		setReadOnly(false);
	}
}
